package com.example.dingdong.shiro;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.SimpleCredentialsMatcher;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


import java.util.LinkedHashMap;
import java.util.Map;

@Configuration
public class ShiroConfiguration {


	private static final Logger log = LoggerFactory.getLogger(ShiroConfiguration.class);


	/**
	 * 验证账户名与密码的类
	 * 
	 * @author
	 *
	 */
	class UserCredentialsMatcher extends SimpleCredentialsMatcher {
		@Override
		public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {

			UsernamePasswordToken usertoken = (UsernamePasswordToken) token;
			String password = (String) info.getCredentials();

			return equals(new String(usertoken.getPassword()), password);
		}
	}

	@Bean
	public CustomCredentialsMatcher getCustomCredentialsMatcher() {
		return new CustomCredentialsMatcher();
	}

	@Bean
	public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
		log.info("ShiroConfiguration.shirFilter()");
		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
		shiroFilterFactoryBean.setSecurityManager(securityManager);

		// 自定义拦截器
//        Map<String, Filter> filtersMap = new LinkedHashMap<>();
//        filtersMap.put("myHttpAuthFilter", getMyHttpAuthFilter());
//        shiroFilterFactoryBean.setFilters(filtersMap);

		// 拦截器.
		Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
		// 配置不会被拦截的链接 顺序判断
		filterChainDefinitionMap.put("/static/**", "anon");
		filterChainDefinitionMap.put("/rest/web/**", "anon");
		filterChainDefinitionMap.put("/web/rest/**", "anon");

		// 配置退出 过滤器,其中的具体的退出代码Shiro已经替我们实现了
//		filterChainDefinitionMap.put("/web/rest/UserRest/logout", "loginOut");
		// <!-- 过滤链定义，从上向下顺序执行，一般将/**放在最为下边 -->:这是一个坑呢，一不小心代码就不好使了;
		// <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
		// filterChainDefinitionMap.put("/**", "authc");

		// 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
		// shiroFilterFactoryBean.setLoginUrl("/login");
		// 登录成功后要跳转的链接
		// shiroFilterFactoryBean.setSuccessUrl("/index");

		// 未授权界面;
		// shiroFilterFactoryBean.setUnauthorizedUrl("/403");
		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
		return shiroFilterFactoryBean;
	}

	@Bean
	public MyShiroRealm myShiroRealm() {
		MyShiroRealm myShiroRealm = new MyShiroRealm();
		myShiroRealm.setCredentialsMatcher(getCustomCredentialsMatcher());
		return myShiroRealm;
	}

	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
		advisor.setSecurityManager(securityManager);
		return advisor;

	}

	/**
	 * 自定义sessionManager
	 */
	@Bean
	public SessionManager sessionManager() {
		DefaultHeaderSessionManager shiroSessionManager = new DefaultHeaderSessionManager();
		// 这里可以不设置。Shiro有默认的session管理。如果缓存为Redis则需改用Redis的管理
		// shiroSessionManager.setSessionDAO(new EnterpriseCacheSessionDAO());
		return shiroSessionManager;
	}

	@Bean
	public SecurityManager securityManager() {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		// 自定义session管理
		securityManager.setSessionManager(sessionManager());
		securityManager.setRealm(myShiroRealm());
		return securityManager;
	}
}
